package com.changgou.user.controller;

import com.alibaba.fastjson.JSON;
import com.changgou.entity.BCrypt;
import com.changgou.entity.JwtUtil;
import com.changgou.entity.Result;
import com.changgou.entity.StatusCode;
import com.changgou.user.pojo.User;
import com.changgou.user.service.UserService;
import com.github.pagehelper.PageInfo;
import io.swagger.annotations.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/****
 * @Author:zhangyuhong
 * @Description:
 * @Date 2019/6/14 0:18
 *****/
@Api(value = "UserController")
@RestController
@RequestMapping("/user")
@CrossOrigin
public class UserController {

    @Autowired
    private UserService userService;

    /***
     * User分页条件搜索实现
     * @param user
     * @param page
     * @param size
     * @return
     */
    @ApiOperation(value = "User条件分页查询",notes = "分页条件查询User方法详情",tags = {"UserController"})
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "path", name = "page", value = "当前页", required = true, dataType = "Integer"),
            @ApiImplicitParam(paramType = "path", name = "size", value = "每页显示条数", required = true, dataType = "Integer")
    })
    @PostMapping(value = "/search/{page}/{size}" )
    public Result<PageInfo> findPage(@RequestBody(required = false) @ApiParam(name = "User对象",value = "传入JSON数据",required = false) User user, @PathVariable(name="page")  int page, @PathVariable(name="page")  int size){
        //调用UserService实现分页条件查询User
        PageInfo<User> pageInfo = userService.findPage(user, page, size);
        return new Result(true,StatusCode.OK,"查询成功",pageInfo);
    }

    /***
     * User分页搜索实现
     * @param page:当前页
     * @param size:每页显示多少条
     * @return
     */
    @ApiOperation(value = "User分页查询",notes = "分页查询User方法详情",tags = {"UserController"})
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "path", name = "page", value = "当前页", required = true, dataType = "Integer"),
            @ApiImplicitParam(paramType = "path", name = "size", value = "每页显示条数", required = true, dataType = "Integer")
    })
    @GetMapping(value = "/search/{page}/{size}" )
    public Result<PageInfo> findPage(@PathVariable(name="page")  int page, @PathVariable(name="size")  int size){
        //调用UserService实现分页查询User
        PageInfo<User> pageInfo = userService.findPage(page, size);
        return new Result<PageInfo>(true,StatusCode.OK,"查询成功",pageInfo);
    }

    /***
     * 多条件搜索品牌数据
     * @param user
     * @return
     */
    @ApiOperation(value = "User条件查询",notes = "条件查询User方法详情",tags = {"UserController"})
    @PostMapping(value = "/search" )
    public Result<List<User>> findList(@RequestBody(required = false) @ApiParam(name = "User对象",value = "传入JSON数据",required = false) User user){
        //调用UserService实现条件查询User
        List<User> list = userService.findList(user);
        return new Result<List<User>>(true,StatusCode.OK,"查询成功",list);
    }

    /***
     * 根据ID删除品牌数据
     * @param id
     * @return
     */
    @ApiOperation(value = "User根据ID删除",notes = "根据ID删除User方法详情",tags = {"UserController"})
    @ApiImplicitParam(paramType = "path", name = "id", value = "主键ID", required = true, dataType = "String")
    @DeleteMapping(value = "/{id}" )
    @PreAuthorize("hasAnyAuthority('admin')")  //有admin角色或者权限才能访问
    public Result delete(@PathVariable(name="id") String id){
        //调用UserService实现根据主键删除
        userService.delete(id);
        return new Result(true,StatusCode.OK,"删除成功");
    }

    /***
     * 修改User数据
     * @param user
     * @param id
     * @return
     */
    @ApiOperation(value = "User根据ID修改",notes = "根据ID修改User方法详情",tags = {"UserController"})
    @ApiImplicitParam(paramType = "path", name = "id", value = "主键ID", required = true, dataType = "String")
    @PutMapping(value="/{id}")
    public Result update(@RequestBody @ApiParam(name = "User对象",value = "传入JSON数据",required = false) User user,@PathVariable(name="id") String id){
        //设置主键值
        user.setUsername(id);
        //调用UserService实现修改User
        userService.update(user);
        return new Result(true,StatusCode.OK,"修改成功");
    }

    /***
     * 新增User数据
     * @param user
     * @return
     */
    @ApiOperation(value = "User添加",notes = "添加User方法详情",tags = {"UserController"})
    @PostMapping
    public Result add(@RequestBody  @ApiParam(name = "User对象",value = "传入JSON数据",required = true) User user){
        //调用UserService实现添加User
        userService.add(user);
        return new Result(true,StatusCode.OK,"添加成功");
    }

    /***
     * 根据ID查询User数据
     * @param id
     * @return
     */
    @ApiOperation(value = "根据ID查询用户",notes = "根据ID查询User方法详情",tags = {"UserController"})
    @ApiImplicitParam(paramType = "path", name = "id", value = "主键ID", required = true, dataType = "String")
    @GetMapping("/{id}")
    public Result<User> findById(@PathVariable(name="id") String id){
        //调用UserService实现根据主键查询User
        User user = userService.findById(id);
        return new Result<User>(true,StatusCode.OK,"查询成功",user);
    }

    /***
     * 根据ID查询User数据,跟前面的是一样的,名字不一样而已
     * @param id
     * @return
     *
     * 认证微服务通过这个查询用户的所有全权限,然后通过 数据库;里的信息  生成token
     */
    @ApiOperation(value = "根据ID查询用户,给授权微服务用的",notes = "根据ID查询User方法详情",tags = {"UserController"})
    @ApiImplicitParam(paramType = "path", name = "id", value = "主键ID", required = true, dataType = "String")
    @GetMapping("/load/{id}")
    public Result<User> loadById(@PathVariable(name="id") String id){
        //调用UserService实现根据主键查询User
        User user = userService.findById(id);
        return new Result<User>(true,StatusCode.OK,"查询成功",user);
    }


    /***
     * 查询User全部数据
     * @return
     */
    @ApiOperation(value = "查询所有User",notes = "查询所User有方法详情",tags = {"UserController"})
    @GetMapping
    public Result<List<User>> findAll(){
        //调用UserService实现查询所有User
        List<User> list = userService.findAll();
        return new Result<List<User>>(true, StatusCode.OK,"查询成功",list) ;
    }

    /***
     * 用户登录
     */
    @RequestMapping(value = "/login")
    public Result login(String username, String password, HttpServletResponse response){
        if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) {
            return new Result(false, StatusCode.LOGINERROR, "登录失败");
        }
        //根据用户名查询用户数据库的数据
        User user = userService.findById(username);
        if (user == null) {
            return new Result(false, StatusCode.LOGINERROR, "登录失败,用户名或密码错误");
        }
        // 判断密码是否正确  数据库的密码是加密的bcrypt
        if(!BCrypt.checkpw(password,user.getPassword())){
            return new Result(false, StatusCode.LOGINERROR, "登录失败,用户名或密码错误");
        }
        //登录成功需要颁发JWT令牌,这样在令牌有效时间内以后他就凭借这个去访问其他的微服务了
        Map<String, Object> map = new HashMap<>();
        map.put("role", "ROLE_SUPER");//超级用户,应该项从数据库中查出来,这里暂时写定,有问题,以后改
        map.put("success", "true");
        map.put("username", username);
        //jwt令牌 包含 头部、载荷与签名。所以要有三个字符串
        //uuid为唯一表示
        String token = JwtUtil.createJWT(UUID.randomUUID().toString(), JSON.toJSONString(map), null);

        //给用户,可以设置到cookies
        Cookie cookie = new Cookie("Authorization",token);
        cookie.setPath("/");  //设置路径  cookie的获取范围
        response.addCookie(cookie);
        return new Result(true, StatusCode.OK, "登录成功",token);
    }

    /**
     * @param username  用户名
     * @param points 增加的积分数量
     * @return
     */
    @ApiOperation("增加用户积分")
    @GetMapping("/points/add")
    public Result addPoints(@RequestParam(name="username") String username,
                            @RequestParam(name="points") Integer points){
        //受影响的行
        Integer count = userService.addPoints(username,points);
        if(count>0){
            return new Result(true,StatusCode.OK,"添加积分成功");
        }else{
            return new Result(false,StatusCode.ERROR,"添加积分失败");
        }
    }



    public static void main(String[] args) {
      /*  String str="{\"typ\":\"JWT\",\"alg\":\"HS256\"}";
        String str2="eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9";

        byte[] decode = Base64.getDecoder().decode(str2);
        System.out.println(new String(decode));
        String string = Base64.getEncoder().encodeToString(str.getBytes());
        System.out.println(string);*/

       /* String hashpw = new BCryptPasswordEncoder().encode("123456");
        System.out.println(hashpw);
        boolean checkpw = BCrypt.checkpw("123456", "$2a$10$uUTVifkE196eZoC9rPOxh.AvHUGD4Tudc2ifQjta80Aqv/0AQ9JEC");
        System.out.println(checkpw);
//        BCrypt.gensalt()*/

        String zhangsan = new BCryptPasswordEncoder().encode("zhangsan");
        System.out.println(zhangsan);
    }
}
